"""
核心服务：两步投资分析流程
1. 提取代币关键字，判断投资价值
2. 如果有价值，进行知识库检索和投资判断
"""

import json
import os
from typing import Dict, Any, List
from openai import APIError, APIConnectionError
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from app.services.knowledge_processor import KnowledgeProcessor
from app.services.metadata_extractor import MetadataExtractor
from app.services.learning_system import LearningSystem

class CoreService:
    """核心服务"""
    
    def __init__(self):
        self.api_key = "sk-gX6NNINB54pDBGRka36jg33fR1fnSOwfu21uC3Wnjmiwv3KB"
        self.api_base = "https://api.chatanywhere.tech/v1"
        
        self.llm = None
        self.embeddings = None
        self.knowledge_processor = KnowledgeProcessor()
        self.metadata_extractor = None
        self.learning_system = LearningSystem()
        self._knowledge_loaded = False
    
    def initialize(self):
        """初始化核心组件"""
        self.llm = ChatOpenAI(
            model="gpt-3.5-turbo",
            temperature=0.7,
            openai_api_key=self.api_key,
            openai_api_base=self.api_base
        )
        self.embeddings = OpenAIEmbeddings(
            openai_api_key=self.api_key,
            openai_api_base=self.api_base
        )
        
        self._initialize_knowledge_base()
        self.metadata_extractor = MetadataExtractor(self.llm)
    
    def _initialize_knowledge_base(self):
        """初始化知识库"""
        if self.knowledge_processor.load_existing_vectorstore():
            self._knowledge_loaded = True
        else:
            if self.knowledge_processor.process_knowledge_base():
                self._knowledge_loaded = True
    
    def analyze_news(self, news_data: Dict[str, Any]) -> Dict[str, Any]:
        """分析快讯 - 两步流程"""
        
        # 第一步：提取代币关键字，判断投资价值
        token_extraction = self._extract_tokens_and_assess_value(news_data)
        
        if not token_extraction['has_value']:
            # 没有投资价值，直接返回
            return {
                "news_id": news_data.get("news_id", ""),
                "token_extraction": token_extraction,
                "status": "no_investment_value",
                "message": "该新闻没有投资价值"
            }
        
        # 第二步：有投资价值，进行知识库检索和投资判断
        metadata = self.metadata_extractor.extract_metadata(news_data)
        queries = self.metadata_extractor.generate_queries(metadata, news_data)
        knowledge = self._search_knowledge(queries, metadata)
        
        # 获取学习增强的提示词
        enhanced_prompt = self.learning_system.get_enhanced_prompt(news_data)
        confidence_adjustment = self.learning_system.get_confidence_adjustment(news_data)
        
        # 分析代币涨跌
        price_analysis = self._analyze_price_movement(news_data, knowledge, enhanced_prompt, confidence_adjustment)
        
        return {
            "news_id": news_data.get("news_id", ""),
            "token_extraction": token_extraction,
            "entities": metadata,
            "queries": queries,
            "knowledge": knowledge,
            "price_analysis": price_analysis,
            "status": "success"
        }
    
    def _extract_tokens_and_assess_value(self, news_data: Dict[str, Any]) -> Dict[str, Any]:
        """第一步：提取代币关键字，判断投资价值"""
        prompt = f"""
请分析以下新闻，提取代币关键字并判断投资价值：

新闻标题：{news_data.get("title", "")}
新闻内容：{news_data.get("content", "")}

任务：
1. 提取新闻中涉及的所有代币符号（如BTC、ETH、ZKS、UNI、SOL、MATIC等）
2. 判断该新闻是否具有投资价值

判断标准：
- 是否涉及代币价格变化
- 是否涉及重大技术升级
- 是否涉及融资、合作、监管等重大事件
- 是否对市场有实质性影响

返回JSON：
{{
    "tokens": ["代币符号1", "代币符号2"],
    "has_value": true/false,
    "value_level": "high/medium/low",
    "reason": "判断原因",
    "key_factors": ["关键因素1", "关键因素2"]
}}
"""
        
        response = self.llm.invoke(prompt)
        return json.loads(response.content)
    
    def _analyze_price_movement(self, news_data: Dict[str, Any], knowledge: List[str], enhanced_prompt: str, confidence_adjustment: float) -> Dict[str, Any]:
        """第二步：分析代币涨跌"""
        knowledge_text = "\n".join(knowledge) if knowledge else "无相关知识"
        
        # 调整置信度
        base_confidence = 0.8
        adjusted_confidence = min(base_confidence + confidence_adjustment, 1.0)
        
        prompt = f"""
{enhanced_prompt}

代币涨跌分析：

新闻：{news_data.get("title", "")} - {news_data.get("content", "")}
知识：{knowledge_text}

请分析代币的涨跌趋势，返回JSON：
{{
    "price_prediction": "up/down/neutral",
    "confidence": {adjusted_confidence},
    "reason": "分析原因",
    "key_factors": ["影响因子1", "影响因子2"],
    "risk_level": "high/medium/low"
}}
"""
        
        response = self.llm.invoke(prompt)
        return json.loads(response.content)
    
    def learn_from_result(self, news_data: Dict, prediction: Dict, actual_result: Dict):
        """从结果中学习"""
        self.learning_system.learn_from_result(news_data, prediction, actual_result)
    
    def _search_knowledge(self, queries: List[Dict[str, Any]], entities: Dict[str, Any]) -> List[str]:
        """检索知识库"""
        if not self.knowledge_processor:
            return []
        
        unique_results = {}
        
        for query_info in queries:
            query_text = query_info.get("query", "").strip()
            if not query_text:
                continue
            
            results = self.knowledge_processor.search_similar_documents(
                query=query_text,
                k=5
            )
            
            for result in results:
                content = result.content
                score = result.similarity_score
                
                if content not in unique_results or unique_results[content][0] < score:
                    unique_results[content] = (score, query_text)
        
        sorted_results = sorted(unique_results.items(), key=lambda x: x[1][0], reverse=True)
        
        knowledge_results = []
        for content, (score, source_query) in sorted_results[:5]:
            knowledge_results.append(f"[相关度: {score:.2f}] {content}")
        
        return knowledge_results